#!/usr/bin/env node

/**
 * SQLite到MongoDB数据迁移脚本
 * 用于将现有的SQLite数据迁移到MongoDB
 */

const sqlite3 = require('sqlite3').verbose();
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const path = require('path');
const fs = require('fs');

// 模型导入
const User = require('../server/src/models/User');
const Message = require('../server/src/models/Message');
const Group = require('../server/src/models/Group');
const Channel = require('../server/src/models/Channel');

class MigrationManager {
  constructor() {
    this.sqliteDb = null;
    this.mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/hallochat';
    this.stats = {
      users: { total: 0, migrated: 0, skipped: 0, errors: 0 },
      messages: { total: 0, migrated: 0, skipped: 0, errors: 0 },
      groups: { total: 0, migrated: 0, skipped: 0, errors: 0 },
      channels: { total: 0, migrated: 0, skipped: 0, errors: 0 }
    };
  }

  async connectSQLite() {
    const dbPath = path.join(__dirname, '../server/database.sqlite');
    
    if (!fs.existsSync(dbPath)) {
      throw new Error(`SQLite数据库文件不存在: ${dbPath}`);
    }

    return new Promise((resolve, reject) => {
      this.sqliteDb = new sqlite3.Database(dbPath, (err) => {
        if (err) {
          reject(err);
        } else {
          console.log('✅ 已连接到SQLite数据库');
          resolve();
        }
      });
    });
  }

  async connectMongoDB() {
    try {
      await mongoose.connect(this.mongoUri, {
        useNewUrlParser: true,
        useUnifiedTopology: true
      });
      console.log('✅ 已连接到MongoDB');
    } catch (error) {
      console.error('❌ MongoDB连接失败:', error.message);
      throw error;
    }
  }

  async querySQLite(sql, params = []) {
    return new Promise((resolve, reject) => {
      this.sqliteDb.all(sql, params, (err, rows) => {
        if (err) {
          reject(err);
        } else {
          resolve(rows);
        }
      });
    });
  }

  async migrateUsers() {
    console.log('🔄 开始迁移用户数据...');
    
    try {
      const users = await this.querySQLite('SELECT * FROM Users');
      this.stats.users.total = users.length;

      for (const user of users) {
        try {
          // 检查用户是否已存在
          const existingUser = await User.findOne({ username: user.username });
          if (existingUser) {
            console.log(`⚠️ 用户已存在，跳过: ${user.username}`);
            this.stats.users.skipped++;
            continue;
          }

          // 创建新用户
          const newUser = new User({
            username: user.username,
            email: user.email || `${user.username}@example.com`,
            password: user.password, // 假设密码已加密
            avatar: user.avatar || null,
            status: user.status || 'offline',
            isOnline: false,
            lastSeen: user.updatedAt || new Date(),
            createdAt: user.createdAt || new Date(),
            updatedAt: user.updatedAt || new Date()
          });

          await newUser.save();
          this.stats.users.migrated++;
          console.log(`✅ 迁移用户: ${user.username}`);

        } catch (error) {
          console.error(`❌ 迁移用户失败 ${user.username}:`, error.message);
          this.stats.users.errors++;
        }
      }

      console.log(`✅ 用户迁移完成: ${this.stats.users.migrated}/${this.stats.users.total}`);
    } catch (error) {
      console.error('❌ 用户迁移错误:', error.message);
      throw error;
    }
  }

  async migrateGroups() {
    console.log('🔄 开始迁移群组数据...');
    
    try {
      const groups = await this.querySQLite('SELECT * FROM Groups');
      this.stats.groups.total = groups.length;

      for (const group of groups) {
        try {
          // 获取创建者
          const creator = await User.findOne({ username: group.creatorUsername });
          if (!creator) {
            console.log(`⚠️ 创建者不存在，跳过群组: ${group.name}`);
            this.stats.groups.skipped++;
            continue;
          }

          // 检查群组是否已存在
          const existingGroup = await Group.findOne({ name: group.name });
          if (existingGroup) {
            console.log(`⚠️ 群组已存在，跳过: ${group.name}`);
            this.stats.groups.skipped++;
            continue;
          }

          // 获取成员
          const members = await this.querySQLite(
            'SELECT userId FROM GroupMembers WHERE groupId = ?',
            [group.id]
          );

          const memberUsers = await User.find({ 
            _id: { $in: members.map(m => m.userId) }
          });

          const newGroup = new Group({
            name: group.name,
            description: group.description || '',
            creator: creator._id,
            members: memberUsers.map(user => ({
              user: user._id,
              role: 'member',
              joinedAt: new Date()
            })),
            avatar: group.avatar || null,
            type: group.type || 'public',
            isActive: true,
            createdAt: group.createdAt || new Date(),
            updatedAt: group.updatedAt || new Date()
          });

          await newGroup.save();
          this.stats.groups.migrated++;
          console.log(`✅ 迁移群组: ${group.name}`);

        } catch (error) {
          console.error(`❌ 迁移群组失败 ${group.name}:`, error.message);
          this.stats.groups.errors++;
        }
      }

      console.log(`✅ 群组迁移完成: ${this.stats.groups.migrated}/${this.stats.groups.total}`);
    } catch (error) {
      console.error('❌ 群组迁移错误:', error.message);
      throw error;
    }
  }

  async migrateChannels() {
    console.log('🔄 开始迁移频道数据...');
    
    try {
      const channels = await this.querySQLite('SELECT * FROM Channels');
      this.stats.channels.total = channels.length;

      for (const channel of channels) {
        try {
          // 获取创建者
          const creator = await User.findOne({ username: channel.creatorUsername });
          if (!creator) {
            console.log(`⚠️ 创建者不存在，跳过频道: ${channel.name}`);
            this.stats.channels.skipped++;
            continue;
          }

          // 获取群组
          const group = await Group.findOne({ name: channel.groupName });
          if (!group) {
            console.log(`⚠️ 群组不存在，跳过频道: ${channel.name}`);
            this.stats.channels.skipped++;
            continue;
          }

          // 检查频道是否已存在
          const existingChannel = await Channel.findOne({ 
            name: channel.name, 
            group: group._id 
          });
          if (existingChannel) {
            console.log(`⚠️ 频道已存在，跳过: ${channel.name}`);
            this.stats.channels.skipped++;
            continue;
          }

          const newChannel = new Channel({
            name: channel.name,
            description: channel.description || '',
            group: group._id,
            creator: creator._id,
            type: channel.type || 'text',
            isActive: true,
            position: channel.position || 0,
            createdAt: channel.createdAt || new Date(),
            updatedAt: channel.updatedAt || new Date()
          });

          await newChannel.save();
          this.stats.channels.migrated++;
          console.log(`✅ 迁移频道: ${channel.name}`);

        } catch (error) {
          console.error(`❌ 迁移频道失败 ${channel.name}:`, error.message);
          this.stats.channels.errors++;
        }
      }

      console.log(`✅ 频道迁移完成: ${this.stats.channels.migrated}/${this.stats.channels.total}`);
    } catch (error) {
      console.error('❌ 频道迁移错误:', error.message);
      throw error;
    }
  }

  async migrateMessages() {
    console.log('🔄 开始迁移消息数据...');
    
    try {
      const messages = await this.querySQLite('SELECT * FROM Messages ORDER BY createdAt ASC');
      this.stats.messages.total = messages.length;

      for (const message of messages) {
        try {
          // 获取发送者
          const sender = await User.findOne({ username: message.senderUsername });
          if (!sender) {
            console.log(`⚠️ 发送者不存在，跳过消息: ${message.id}`);
            this.stats.messages.skipped++;
            continue;
          }

          // 获取接收者或群组
          let receiver = null;
          let group = null;
          let channel = null;

          if (message.receiverUsername) {
            receiver = await User.findOne({ username: message.receiverUsername });
          } else if (message.groupName) {
            group = await Group.findOne({ name: message.groupName });
          } else if (message.channelName && message.groupName) {
            group = await Group.findOne({ name: message.groupName });
            if (group) {
              channel = await Channel.findOne({ 
                name: message.channelName, 
                group: group._id 
              });
            }
          }

          const newMessage = new Message({
            content: message.content || '',
            type: message.type || 'text',
            sender: sender._id,
            receiver: receiver ? receiver._id : null,
            group: group ? group._id : null,
            channel: channel ? channel._id : null,
            isEdited: message.isEdited || false,
            isDeleted: message.isDeleted || false,
            createdAt: message.createdAt || new Date(),
            updatedAt: message.updatedAt || new Date()
          });

          await newMessage.save();
          this.stats.messages.migrated++;

          if (this.stats.messages.migrated % 100 === 0) {
            console.log(`✅ 已迁移 ${this.stats.messages.migrated}/${this.stats.messages.total} 条消息`);
          }

        } catch (error) {
          console.error(`❌ 迁移消息失败 ${message.id}:`, error.message);
          this.stats.messages.errors++;
        }
      }

      console.log(`✅ 消息迁移完成: ${this.stats.messages.migrated}/${this.stats.messages.total}`);
    } catch (error) {
      console.error('❌ 消息迁移错误:', error.message);
      throw error;
    }
  }

  async generateReport() {
    console.log('\n📊 迁移报告:');
    console.log('='.repeat(50));
    console.log(`用户: ${this.stats.users.migrated}/${this.stats.users.total} (跳过: ${this.stats.users.skipped}, 错误: ${this.stats.users.errors})`);
    console.log(`群组: ${this.stats.groups.migrated}/${this.stats.groups.total} (跳过: ${this.stats.groups.skipped}, 错误: ${this.stats.groups.errors})`);
    console.log(`频道: ${this.stats.channels.migrated}/${this.stats.channels.total} (跳过: ${this.stats.channels.skipped}, 错误: ${this.stats.channels.errors})`);
    console.log(`消息: ${this.stats.messages.migrated}/${this.stats.messages.total} (跳过: ${this.stats.messages.skipped}, 错误: ${this.stats.messages.errors})`);
    console.log('='.repeat(50));

    const totalMigrated = this.stats.users.migrated + this.stats.groups.migrated + 
                         this.stats.channels.migrated + this.stats.messages.migrated;
    const totalRecords = this.stats.users.total + this.stats.groups.total + 
                        this.stats.channels.total + this.stats.messages.total;

    console.log(`总计: ${totalMigrated}/${totalRecords} 条记录已迁移`);
    console.log(`成功率: ${((totalMigrated / totalRecords) * 100).toFixed(2)}%`);
  }

  async run() {
    try {
      console.log('🚀 开始SQLite到MongoDB数据迁移...\n');

      // 连接数据库
      await this.connectSQLite();
      await this.connectMongoDB();

      // 清理现有数据（可选）
      if (process.env.CLEAN_BEFORE_MIGRATE === 'true') {
        console.log('🧹 清理现有MongoDB数据...');
        await User.deleteMany({});
        await Group.deleteMany({});
        await Channel.deleteMany({});
        await Message.deleteMany({});
        console.log('✅ 清理完成');
      }

      // 执行迁移
      await this.migrateUsers();
      await this.migrateGroups();
      await this.migrateChannels();
      await this.migrateMessages();

      // 生成报告
      await this.generateReport();

      console.log('\n✅ 迁移完成！');

    } catch (error) {
      console.error('❌ 迁移失败:', error);
      throw error;
    } finally {
      // 关闭连接
      if (this.sqliteDb) {
        this.sqliteDb.close();
      }
      await mongoose.disconnect();
    }
  }
}

// 运行迁移
if (require.main === module) {
  const migration = new MigrationManager();
  migration.run().catch(console.error);
}

module.exports = MigrationManager;